package com.chinatechstar.prediction.controller;

import java.io.IOException;
import java.util.*;

import javax.servlet.http.HttpServletResponse;

import com.chinatechstar.prediction.dto.PredictionPressureDTO;
import com.chinatechstar.prediction.dto.PredictionPressureDetailDTO;
import com.chinatechstar.prediction.entity.Trend;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.chinatechstar.prediction.entity.PredictionPressure;
import com.chinatechstar.prediction.service.PredictionPressureService;
import com.chinatechstar.component.commons.result.ActionResult;
import com.chinatechstar.component.commons.result.ListResult;
import com.chinatechstar.component.commons.result.ResultBuilder;
import com.chinatechstar.component.commons.utils.ExcelUtils;
import com.chinatechstar.component.commons.validator.InsertValidator;
import com.chinatechstar.component.commons.validator.UpdateValidator;

/**
 * 注入压力预测 的控制层
 */
@Api(value = "注入压力预测 的控制层", tags = {"注入压力预测"})
@RestController
@RequestMapping("/predictionpressure")
public class PredictionPressureController {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private PredictionPressureService predictionPressureService;

    /**
     * 查询 注入压力预测 所有数据
     *
     * @return ListResult<Object>
     */
    @ApiOperation(value = "查询 注入压力预测 所有数据", tags = {"注入压力预测"})
    @GetMapping(path = "/findPredictionPressureAll")
    public ListResult<Object> findPredictionPressureAll() {
        List<PredictionPressure> list = predictionPressureService.findPredictionPressureAll();
        return ResultBuilder.buildListSuccess(list);
    }


    /**
     * 查询 注入压力预测 分页
     *
     * @param currentPage   当前页数
     * @param pageSize      每页记录数
     * @param wellName      井名
     * @param planName      方案名
     * @return ListResult<Object>
     */
    @ApiOperation(value = "查询 注入压力预测 分页", tags = {"注入压力预测"})
    @GetMapping(path = "/findPredictionPressureByCondition")
    public ListResult<Object> findPredictionPressureByCondition(@RequestParam(name = "currentPage", required = false, defaultValue = "1") Integer currentPage,
                                                           @RequestParam(name = "pageSize", required = false, defaultValue = "10") Integer pageSize,
                                                             @RequestParam(name = "wellName", required = false) String wellName,
                                                             @RequestParam(name = "planName", required = false) String planName,
                                                           @RequestParam(name = "sorter", required = false) String sorter) {
        Map<String, Object> data = predictionPressureService.findPredictionPressureByCondition(currentPage, pageSize, wellName, planName, sorter);
        return ResultBuilder.buildListSuccess(data);
    }

    /**
     * 导出注入压力预测数据

     */
    @ApiOperation(value = "导出注入压力预测数据", tags = {"注入压力预测数据"})
    @GetMapping(path = "/exportPredictionPressure")
    public void exportPredictionPressure(HttpServletResponse response) throws IOException {
        predictionPressureService.exportPredictionPressure(response);
    }

    /**
     * 根据主键ID查询 注入压力预测 数据
     *
     * @param id ID
     * @return ActionResult
     */
    @ApiOperation(value = "根据主键ID数据查询 注入压力预测 数据", tags = {"注入压力预测"})
    @GetMapping(path = "/findPredictionPressureById")
    public ActionResult findPredictionPressureById(@RequestParam(name = "id") Long id) {
        PredictionPressure data = predictionPressureService.findPredictionPressureById(id);
        return ResultBuilder.buildActionSuccess(data);
    }

    /**
     * 根据主键ID数组查询 注入压力预测 数据
     *
     * @param ids ID数组
     * @return ActionResult
     */
    @ApiOperation(value = "根据主键ID数组查询 注入压力预测 数据", tags = {"注入压力预测"})
    @GetMapping(path = "/findPredictionPressureByIds")
    public ListResult<Object> findPredictionPressureByIds(@RequestParam(name = "ids") Long[] ids) {
        List<PredictionPressure> list = predictionPressureService.findPredictionPressureByIds(ids);
        return ResultBuilder.buildListSuccess(list);
    }

    /**
     * 新增 注入压力预测
     *
     * @param predictionPressure 注入压力预测 实体
     * @return ActionResult
     */
    @ApiOperation(value = "新增 注入压力预测", tags = {"注入压力预测"})
    @PostMapping(path = "/addPredictionPressure")
    public ActionResult addPredictionPressure(@Validated(InsertValidator.class) @RequestBody PredictionPressure predictionPressure) {
        predictionPressureService.insertPredictionPressure(predictionPressure);
        return ResultBuilder.buildActionSuccess();
    }

    /**
     * 批量新增 注入压力预测
     *
     * @param predictionPressures 注入压力预测 实体数组
     * @return ActionResult
     */
    @ApiOperation(value = "批量新增 注入压力预测", tags = {"注入压力预测"})
    @PostMapping(path = "/addPredictionPressures")
    public ActionResult addPredictionPressures(@Validated(InsertValidator.class) @RequestBody List<PredictionPressure> predictionPressures) {
        predictionPressureService.insertPredictionPressures(predictionPressures);
        return ResultBuilder.buildActionSuccess();
    }

    /**
     * 编辑 注入压力预测
     *
     * @param predictionPressure 注入压力预测 实体
     * @return ActionResult
     */
    @ApiOperation(value = "编辑 注入压力预测", tags = {"注入压力预测"})
    @PutMapping(path = "/updatePredictionPressure")
    public ActionResult updatePredictionPressure(@Validated(UpdateValidator.class) @RequestBody PredictionPressure predictionPressure) {
        predictionPressureService.updatePredictionPressure(predictionPressure);
        return ResultBuilder.buildActionSuccess();
    }

    /**
     * 批量编辑 注入压力预测
     *
     * @param predictionPressures 注入压力预测 实体数组
     * @return ActionResult
     */
    @ApiOperation(value = "批量编辑 注入压力预测", tags = {"注入压力预测"})
    @PostMapping(path = "/updatePredictionPressures")
    public ActionResult updatePredictionPressures(@Validated(UpdateValidator.class) @RequestBody List<PredictionPressure> predictionPressures) {
        predictionPressureService.updatePredictionPressures(predictionPressures);
        return ResultBuilder.buildActionSuccess();
    }

    /**
     * 删除 注入压力预测
     *
     * @param id ID
     * @return ActionResult
     */
    @ApiOperation(value = "根据主键ID删除 注入压力预测", tags = {"注入压力预测"})
    @PostMapping(path = "/deletePredictionPressureById")
    public ActionResult deletePredictionPressureById(@RequestParam(name = "id") Long id) {
        predictionPressureService.deletePredictionPressureById(id);
        return ResultBuilder.buildActionSuccess();
    }

    /**
     * 删除 注入压力预测
     *
     * @param ids ID数组
     * @return ActionResult
     */
    @ApiOperation(value = "根据主键ID数组批量删除 注入压力预测", tags = {"注入压力预测"})
    @PostMapping(path = "/deletePredictionPressureByIds")
    public ActionResult deletePredictionPressureByIds(@RequestParam(name = "id") Long[] ids) {
        predictionPressureService.deletePredictionPressureByIds(ids);
        return ResultBuilder.buildActionSuccess();
    }

    /**
     * 根据压力和温度查询CO2密度
     *
     * @param formationPressure 压力
     * @param formationTemperature 温度
     */
    @ApiOperation(value = "根据压力和温度查询CO2密度", tags = {"CO2密度"})
    @GetMapping(path = "/findWellCo2DensityByPressureAndTemperature")
    public ListResult<Object> findWellCo2DensityByPressureAndTemperature(@RequestParam(name = "formationPressure") Double formationPressure,
                                                                 @RequestParam(name = "formationTemperature") Double formationTemperature) {
        List<PredictionPressureDTO> data = predictionPressureService.findWellCo2Density(formationPressure, formationTemperature);
        return ResultBuilder.buildListSuccess(data);
    }
    /**
     * 根据注入压力预测id获取详情或子级
     *
     * @param id 注入压力预测ID
     * @return ActionResult
     */
    @ApiOperation(value = "根据注入压力预测id获取详情或子级", tags = {"注入压力预测"})
    @GetMapping(path = "/getPressureDetail")
    public ActionResult getPressureDetail(@RequestParam(name = "id") Long id) {
        PredictionPressureDetailDTO dto = predictionPressureService.getPressureDetail(id);
        return ResultBuilder.buildActionSuccess(dto);
    }
    /**
     * 计算 注入压力
     *
     * @param predictionPressure 注入压力预测 实体
     *
     */
    @ApiOperation(value = "计算 注入压力预测", tags = {"注入压力预测"})
    @PostMapping(path = "/calculatePredictionPressure")
    public PredictionPressure calculatePredictionPressure(  PredictionPressure predictionPressure) {
        return predictionPressureService.calculatePredictionPressure(predictionPressure);
    }

    /**
     * 计算 注入压力
     *
     * @param  wellName 井名
     * @param  wellType 井类型
     * @param  planName 方案名称
     * @param  injectionDepth 垂深
     * @param  formationPressure 地层压力
     * @param  formationTemperature 地层温度
     * @param  permeability 渗透率
     * @param  injectionThickness 注入厚度
     * @param  injectionLength 注入段长度
     * @param  wellHeadDensity 井口密度
     * @param  dailyInjection 日注入量
     */
    @ApiOperation(value = "计算 注入压力预测", tags = {"注入压力预测"})
    @PostMapping(path = "/calculatePredictionPressure2")
    public PredictionPressure calculatePredictionPressure2(  @RequestParam(name = "wellName",required = false) String wellName,
                                                       @RequestParam(name = "wellType",required = false) String wellType,
                                                       @RequestParam(name = "planName",required = false) String planName,
                                                       @RequestParam(name = "injectionDepth",required = false) Double injectionDepth,
                                                       @RequestParam(name = "formationPressure",required = false) Double formationPressure,
                                                       @RequestParam(name = "formationTemperature",required = false) Double formationTemperature,
                                                       @RequestParam(name = "permeability",required = false) Double permeability,
                                                       @RequestParam(name = "injectionThickness",required = false) Double injectionThickness,
                                                       @RequestParam(name = "injectionLength",required = false) Double injectionLength,
                                                       @RequestParam(name = "wellHeadDensity",required = false) Double wellHeadDensity,
                                                       @RequestParam(name = "dailyInjection",required = false) Double dailyInjection,
                                                       @RequestParam(name = "createTime",required = false) String createTime) {
        List<PredictionPressureDTO> data1=new ArrayList<PredictionPressureDTO>();
        List<PredictionPressureDTO> data2=new ArrayList<PredictionPressureDTO>();
        double wellBottomDensity=0;
        double wellBottomViscosity=0;
        double formationPressure1=Math.round(formationPressure);
        if(formationTemperature%5==0){
            data1=predictionPressureService.findWellCo2Density(formationPressure1,formationTemperature);
            data2=predictionPressureService.findWellCo2Density(formationPressure1,(formationTemperature+5.0));
            wellBottomDensity=data1.get(0).getCo2WellBottomDensity();
            wellBottomViscosity=data1.get(0).getCo2WellBottomViscosity();
        }
        else if(data1!=null && data1.size()==0 && data2 !=null && data2.size()==0){
            data1=predictionPressureService.findWellCo2Density(formationPressure1,(Math.floor(formationTemperature/5)*5));
            data2=predictionPressureService.findWellCo2Density(formationPressure1,((Math.floor(formationTemperature/5)+1)*5));
            wellBottomDensity=Trend.trendValue(data1.get(0).getCo2WellBottomDensity(),data1.get(0).getCo2FormationTemperature(),formationTemperature,data2.get(0).getCo2WellBottomDensity(),data2.get(0).getCo2FormationTemperature());
            wellBottomViscosity=Trend.trendValue(data1.get(0).getCo2WellBottomViscosity(),data1.get(0).getCo2FormationTemperature(),formationTemperature,data2.get(0).getCo2WellBottomViscosity(),data2.get(0).getCo2FormationTemperature());
        }
        PredictionPressure predictionPressure=new PredictionPressure();
        predictionPressure.setWellName(wellName);
        predictionPressure.setWellType(wellType);
        predictionPressure.setPlanName(planName);
        predictionPressure.setInjectionDepth(injectionDepth);
        predictionPressure.setFormationPressure(formationPressure);
        predictionPressure.setFormationTemperature(formationTemperature);
        predictionPressure.setPermeability(permeability);
        predictionPressure.setInjectionThickness(injectionThickness);
        predictionPressure.setInjectionLength(injectionLength);
        predictionPressure.setWellHeadDensity(wellHeadDensity);
        predictionPressure.setWellBottomDensity(wellBottomDensity/1000);
        predictionPressure.setWellBottomViscosity(wellBottomViscosity);
        predictionPressure.setDailyInjection(dailyInjection);
        return predictionPressureService.calculatePredictionPressure(predictionPressure);
    }
}
